import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;

import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.PlayerListener;

import net.sf.microlog.core.Logger;
import net.sf.microlog.core.LoggerFactory;
import net.sf.microlog.core.PropertyConfigurator;


public class PlayerManager implements PlayerListener {

	private static PlayerManager pm = null;
	private Player player = null;
	private Hashtable media = null;
	private Hashtable mediaInfo = null;
	private String mediaToPlay;
	
	private static final Logger logger = LoggerFactory.getLogger(PlayerManager.class);
	
	public static final String MEDIA1 = "media1";
	public static final String MEDIA2 = "media2";
	
	public static PlayerManager getPlayerManager() {
		if(pm == null) {
			logger.debug("creating PlayerManager");
			pm = new PlayerManager();
		}
		
		return pm;
	}
	
	private PlayerManager() {
		init();
	}
	
	private void init() {
		
//		PropertyConfigurator.configure("/microlog.properties"); //loads the configuration file
		
		media = new Hashtable();
		mediaInfo = new Hashtable();
		
		mediaToPlay = MEDIA1;
		
		media.put(MEDIA1, "media1.wav");
		mediaInfo.put(MEDIA1, "audio/x-wav");
		
		media.put(MEDIA2, "media2.wav");
		mediaInfo.put(MEDIA2, "audio/x-wav");
	}

	public String getMediaToPlay() {
		return mediaToPlay;
	}

	public void setMediaToPlay(String mediaToPlay) {
		this.mediaToPlay = mediaToPlay;
	}

	public Player getPlayer(String trackKey) {
		
		try {
			InputStream track = getClass().getResourceAsStream((String) media.get(trackKey));
			player = Manager.createPlayer(track, (String) mediaInfo.get(trackKey));
			player.addPlayerListener(this);
			player.setLoopCount(-1);
			player.prefetch();
			player.realize();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (MediaException e) {
			e.printStackTrace();
		}
		
		return player;
	}
	
	public void startPlayer() {
		
		if(player == null || player.getState() == Player.UNREALIZED || player.getState() == Player.CLOSED) {
			player = getPlayer(mediaToPlay);
		}
		
		try {
			player.start();
		} catch (MediaException e) {
			e.printStackTrace();
		}
	}
	
	public void stopPlayer() {
		
		if(player != null && player.getState() == Player.STARTED) {
			try {
				player.stop();
			} catch (MediaException e) {
				e.printStackTrace();
			}
		}
	}

	public void closePlayer() {
		if(player != null)
			player.close();
	}
	
	/* Handle player events */
	public void playerUpdate(Player player, String event, Object eventData) {

		// if the event is that the player has started, show the form
		// but only if the event data indicates that the event relates to newly
		// stated player, as the STARTED event is fired even if a player is
		// restarted. Note that eventData indicates the time at which the start
		// event is fired.
		if(event.equals(PlayerListener.STARTED)) {
			logger.debug("Player started");
		} 
		else if(event.equals(PlayerListener.STOPPED)) {
			logger.debug("Player stopped");
		}
		else if(event.equals(PlayerListener.CLOSED)) {
			logger.debug("Player closed");
		}
		else if(event.equals(PlayerListener.ERROR)) {
			logger.error("Player error");
		}
	}
}
